class_name PropertyData_Int
extends PropertyData

## 计算的原始值 = 实际值 * 百分比值
## modifier先计算实际值，再计算百分比值
## 百分比值的modifier只会求总和起作用

# 实际值
@export var value:int
# 百分比值
@export var percent_value:float = 1
# 是否限制范围
@export var is_limit_range:bool
# 限制范围
@export var limit_range:Vector2i

func get_property():
	var val = property_value_last_modified_func.call(value * percent_value) if property_value_last_modified_func else value * percent_value
	if is_limit_range:
		val = clamp(val,limit_range.x,limit_range.y)
	return val
func get_modified_property():
	match calc_type:
		PropertyDataCalcType.Max:
			var final_val = value
			var final_percent_value = _get_modified_percent_value()
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return not m.is_percent):
				if not final_val:
					final_val = modifier.value
				else:
					final_val = max(final_val,modifier.value)
			var val = property_value_last_modified_func.call(final_val * final_percent_value) if property_value_last_modified_func else final_val * final_percent_value
			if is_limit_range:
				val = clamp(val,limit_range.x,limit_range.y)
			return val
		PropertyDataCalcType.Min:
			var final_val = value
			var final_percent_value = _get_modified_percent_value()
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return not m.is_percent):
				if not final_val:
					final_val = modifier.value
				else:
					final_val = min(final_val,modifier.value)
			var val = property_value_last_modified_func.call(final_val * final_percent_value) if property_value_last_modified_func else final_val * final_percent_value
			if is_limit_range:
				val = clamp(val,limit_range.x,limit_range.y)
			return val
		PropertyDataCalcType.Add:
			var final_val = value
			var final_percent_value = _get_modified_percent_value()
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return not m.is_percent):
				final_val += modifier.value
			var val = property_value_last_modified_func.call(final_val * final_percent_value) if property_value_last_modified_func else final_val * final_percent_value
			if is_limit_range:
				val = clamp(val,limit_range.x,limit_range.y)
			return val
		PropertyDataCalcType.Mul:
			var final_val = value
			var final_percent_value = _get_modified_percent_value()
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return not m.is_percent):
				final_val *= modifier.value
			var val = property_value_last_modified_func.call(final_val * final_percent_value) if property_value_last_modified_func else final_val * final_percent_value
			if is_limit_range:
				val = clamp(val,limit_range.x,limit_range.y)
			return val
		PropertyDataCalcType.OneAdd:
			var final_val = 1
			var final_percent_value = _get_modified_percent_value()
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return not m.is_percent):
				final_val += modifier.value
			final_val = value * final_val
			var val = property_value_last_modified_func.call(final_val * final_percent_value) if property_value_last_modified_func else final_val * final_percent_value
			if is_limit_range:
				val = clamp(val,limit_range.x,limit_range.y)
			return val
		PropertyDataCalcType.InOneAdd:
			var final_val = 1
			var final_percent_value = _get_modified_percent_value()
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return not m.is_percent):
				final_val += modifier.value
			final_val = value / final_val if final_val != 0 else INF
			var val = property_value_last_modified_func.call(final_val * final_percent_value) if property_value_last_modified_func else final_val * final_percent_value
			if is_limit_range:
				val = clamp(val,limit_range.x,limit_range.y)
			return val
		_:
			var final_percent_value = _get_modified_percent_value()
			var val = property_value_last_modified_func.call(value * final_percent_value) if property_value_last_modified_func else value * final_percent_value
			if is_limit_range:
				val = clamp(val,limit_range.x,limit_range.y)
			return val
# 检查能否改变property
func check_can_change_property(change_value) -> bool:
	## TODO 此处先默认如果加上超了上限就返回false
	value += change_value
	var modified_value = get_modified_property()
	if is_limit_range and modified_value < limit_range.x or modified_value > limit_range.y:
		value -= change_value
		return false
	return true
# 抽象方法，子类必须实现
func change_property(change_value):
	if not check_can_change_property(change_value):
		return false
	var last_modified_value = get_modified_property()
	value += change_value
	property_data_changed.emit(last_modified_value,get_modified_property())


func _get_modified_percent_value():
	match percent_calc_type:
		PropertyDataCalcType.Max:
			var final_val = percent_value
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return m.is_percent):
				if not final_val:
					final_val = modifier.value
				else:
					final_val = max(final_val,modifier.value)
			return final_val
		PropertyDataCalcType.Min:
			var final_val = percent_value
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return m.is_percent):
				if not final_val:
					final_val = modifier.value
				else:
					final_val = min(final_val,modifier.value)
			return final_val
		PropertyDataCalcType.Add:
			var final_val = percent_value
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return m.is_percent):
				final_val += modifier.value
			return final_val
		PropertyDataCalcType.Mul:
			var final_val = percent_value
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return m.is_percent):
				final_val *= modifier.value
			return final_val
		PropertyDataCalcType.OneAdd:
			var final_val = 1
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return m.is_percent):
				final_val += modifier.value
			final_val = percent_value * final_val
			return final_val
		PropertyDataCalcType.InOneAdd:
			var final_val = 1
			for modifier:PropertyModifier in property_modifiers.filter(func(m):return m.is_percent):
				final_val += modifier.value
			final_val = percent_value / final_val if final_val != 0 else INF
			return final_val
		_:
			return percent_value
